import React from 'react';
import { Button, Field, Message, Balloon } from '@teamix/ui';
import {
  getScopes,
  deleteToken,
  getTokenList,
} from 'components/PersonalSettings/components/utils/api/index';
import { ButtonIcon } from '@alife/devops-ui';
import './index.scss';
import intl from 'components/PersonalSettings/components/locale';
import SelectScope from './selectScope';
import List from '@txdfe/at-list';
import ListEmpty from 'components/PersonalSettings/components/ListEmpty';
import ListLoading from 'components/PersonalSettings/components/ListLoading';
import Item from './item';

const prefix = 'personal-access-token';
const pageSize = 100;

const arrText = [
  {
    description: '用户相关API的全部读/写权限',
    scope: 'user',
    sub_scopes: [{ description: '用户相关API的只读权限', scope: 'read:user', sub_scopes: [] }],
  },
  {
    description: '代码库全部资源的读/写权限',
    scope: 'repo',
    sub_scopes: [
      {
        description: '代码库全部资源的只读权限，支持 HTTP 或 API 使用',
        scope: 'read:repo',
        sub_scopes: [],
      },
      {
        description: '代码库全部资源的只写权限，支持 HTTP 或 API 使用',
        scope: 'write:repo',
        sub_scopes: [],
      },
      {
        description: '代码库合并请求相关API的读/写权限',
        scope: 'repo:cr',
        sub_scopes: [
          { description: '代码库合并请求相关API的只读权限', scope: 'read:repo:cr', sub_scopes: [] },
          {
            description: '代码库合并请求相关API的只写权限',
            scope: 'write:repo:cr',
            sub_scopes: [],
          },
        ],
      },
      {
        description: '代码库文件相关API的读/写权限',
        scope: 'repo:file',
        sub_scopes: [
          { description: '代码库文件相关API的只读权限', scope: 'read:repo:file', sub_scopes: [] },
          { description: '代码库文件相关API的只写权限', scope: 'write:repo:file', sub_scopes: [] },
        ],
      },
      {
        description: '代码库分支相关API的读/写权限',
        scope: 'repo:branch',
        sub_scopes: [
          { description: '代码库分支相关API的只读权限', scope: 'read:repo:branch', sub_scopes: [] },
          {
            description: '代码库分支相关API的只写权限',
            scope: 'write:repo:branch',
            sub_scopes: [],
          },
        ],
      },
      {
        description: '代码库标签相关API的读/写权限',
        scope: 'repo:tag',
        sub_scopes: [
          { description: '代码库标签相关API的只读权限', scope: 'read:repo:tag', sub_scopes: [] },
          { description: '代码库标签相关API的只写权限', scope: 'write:repo:tag', sub_scopes: [] },
        ],
      },
      {
        description: '代码库成员相关API的读/写权限',
        scope: 'repo:member',
        sub_scopes: [
          { description: '代码库成员相关API的只读权限', scope: 'read:repo:member', sub_scopes: [] },
          {
            description: '代码库成员相关API的只写权限',
            scope: 'write:repo:member',
            sub_scopes: [],
          },
        ],
      },
      {
        description: '代码库提交相关API的读/写权限',
        scope: 'repo:commit',
        sub_scopes: [
          { description: '代码库提交相关API的只读权限', scope: 'read:repo:commit', sub_scopes: [] },
          {
            description: '代码库提交相关API的只写权限',
            scope: 'write:repo:commit',
            sub_scopes: [],
          },
        ],
      },
      {
        description: '代码库 hook 相关API的读/写权限',
        scope: 'repo:webhook',
        sub_scopes: [
          {
            description: '代码库 hook 相关API的只读权限',
            scope: 'read:repo:webhook',
            sub_scopes: [],
          },
          {
            description: '代码库 hook 相关API的只写权限',
            scope: 'write:repo:webhook',
            sub_scopes: [],
          },
        ],
      },
      {
        description: '代码库部署密钥相关API的读/写权限',
        scope: 'repo:deploy_key',
        sub_scopes: [
          {
            description: '代码库部署密钥相关API的只读权限',
            scope: 'read:repo:deploy_key',
            sub_scopes: [],
          },
          {
            description: '代码库部署密钥相关API的只写权限',
            scope: 'write:repo:deploy_key',
            sub_scopes: [],
          },
        ],
      },
    ],
  },
  {
    description: '企业信息相关API的全部读/写权限',
    scope: 'org',
    sub_scopes: [{ description: '企业信息相关API的只读权限', scope: 'read:org', sub_scopes: [] }],
  },
  {
    description: '代码组全部API的读/写权限',
    scope: 'group',
    sub_scopes: [
      { description: '代码组全部API的只读权限', scope: 'read:group', sub_scopes: [] },
      { description: '代码组全部API的只写权限', scope: 'write:group', sub_scopes: [] },
      {
        description: '代码组成员相关API的读/写权限',
        scope: 'group:member',
        sub_scopes: [
          {
            description: '代码组成员相关API的只读权限',
            scope: 'read:group:member',
            sub_scopes: [],
          },
          {
            description: '代码组成员相关API的只写权限',
            scope: 'write:group:member',
            sub_scopes: [],
          },
        ],
      },
    ],
  },
];
const arrTextZhcn = { user: '用户', repo: '代码库', group: '代码组', org: '企业' };

export default class PersonalAccessToken extends React.Component {
  constructor(props) {
    super(props);

    this.changeUsernameField = new Field(this);
    this.setHttpsCloneSecretField = new Field(this);
    this.resetHttpsCloneSecretField = new Field(this);

    this.state = {
      isLoadingList: false,
      scopes: [],
      list: [],
      isModalShow: false,
      modalData: null,
      modalType: 'new',
      newToken: null,
      curPage: 1,
      total: 0,
    };
  }

  componentDidMount() {
    this.getList(1);
    this.getTokenScopes();
  }

  getList = (page = 1) => {
    const { list } = this.state;
    if (page === 1) {
      this.setState({
        isLoadingList: true,
      });
    }
    getTokenList({
      vpc: this.props.vpc,
      page,
      per_page: pageSize,
      order_by: 'update_time',
    })
      .then((res) => {
        if (this.props.vpc) {
          const { result } = res;
          this.setState({
            list: page === 1 ? result.list : [...list, ...result.list],
            isLoadingList: false,
            curPage: page,
            total: result.amount,
          });
        } else {
          this.setState({
            list: page === 1 ? res.list : [...list, ...res.list],
            isLoadingList: false,
            curPage: page,
            total: res.amount,
          });
        }
      })
      .catch((err) => {
        this.setState({
          isLoadingList: false,
        });
        this.toastErrorFromApi(err);
      });
  };

  getTokenScopes = () => {
    getScopes({ vpc: this.props.vpc })
      .then(() => {
        // res
        // const { result } = res;
        const treeData = this.getNamesByType(arrText);
        this.setState({
          // scopes: result,
          scopes: treeData,
        });
      })
      .catch((err) => {
        this.toastErrorFromApi(err);
      });
  };

  toastErrorFromApi(err) {
    try {
      const errCause = err.data.message;
      Message.error({
        title: errCause,
      });
    } catch (e) {
      console.error(e);
    }
  }

  toastSuccess(msg) {
    Message.success({
      title: msg,
    });
  }

  toastError(msg) {
    Message.error({
      title: msg,
    });
  }

  getchildrenName = (array) => {
    const value = array.map((va) => {
      return {
        label: this.getTreeNameNode(va),
        des: va.description,
        key: va.scope,
        children:
          va.sub_scopes && va.sub_scopes.length > 0 ? this.getchildrenName(va.sub_scopes) : [],
      };
    });
    return value;
  };

  getNamesByType = (target) => {
    const newArray =
      target &&
      target.length > 0 &&
      target.map((va) => {
        if (va.sub_scopes && va.sub_scopes.length > 0) {
          return {
            label: this.getTreeNameNode(va),
            des: va.description,
            key: va.scope,
            children: this.getchildrenName(va.sub_scopes),
          };
        } else {
          return {
            label: this.getTreeNameNode(va),
            des: va.description,
            key: va.scope,
            children: [],
          };
        }
      });
    return newArray;
  };

  getTreeNameNode = (va) => {
    return (
      <div>
        <span style={{ width: 200, display: 'inline-block' }}>
          {arrTextZhcn[va.scope] || va.scope}
        </span>
        <span>{va.description}</span>
      </div>
    );
  };

  onCheck(keys, info) {
    console.log('onCheck', keys, info);
  }

  renderTitle = () => {
    return (
      <div className={`${prefix}-header`}>
        <div className={`${prefix}-header-title`}>
          {intl.get('personal_access_token')}
          <Balloon
            closable={false}
            type="normal"
            trigger={
              <ButtonIcon
                type="secondary"
                name="question-line"
                style={{ marginLeft: 4, display: 'inline-block' }}
              />
            }
            align="t"
          >
            <a
              href={
                this.props.vpc
                  ? this.props.vpc_doc['personal-access-token']
                  : 'https://help.aliyun.com/document_detail/314702.html'
              }
              target="_blank"
              rel="noreferrer"
            >
              查看帮助文档
            </a>
          </Balloon>
        </div>
        <div className={`${prefix}-header-desc`}>{intl.get('personal_access_token_desc')}</div>
      </div>
    );
  };

  onDeleteClick = (id) => {
    deleteToken(id, this.props.vpc)
      .then(() => {
        this.getList(1);
        this.toastSuccess(`${intl.get('personal_access_token')}删除成功`);
      })
      .catch(() => {
        this.toastError(`${intl.get('personal_access_token')}删除失败`);
      });
  };

  renderList = () => {
    const { list, newToken, curPage, total, isLoadingList } = this.state;
    let listJsx = null;
    if (isLoadingList) {
      listJsx = <ListLoading />;
    } else if (!(list && list.length)) {
      listJsx = <ListEmpty content={intl.get('no_data')} imgType="data" />;
    } else {
      listJsx = (
        <div style={{ paddingBottom: 20 }}>
          <List
            className="cr-list"
            pagination={{
              onLoadMore: (page) => {
                this.getList(page);
              },
              hasMore: curPage * pageSize < total,
              useWindow: false,
              getScrollParent: () => {
                return document.querySelector('#content-panel');
              },
            }}
          >
            {list.map((item) => {
              return (
                <Item
                  item={item}
                  newToken={newToken}
                  updateData={(data) => {
                    this.setState({ ...data });
                  }}
                  onDeleteClick={this.onDeleteClick}
                />
              );
            })}
          </List>
        </div>
      );
    }

    return (
      <div className={`${prefix}-list-container`}>
        <div className={`${prefix}-list-header`}>
          <div className={`${prefix}-list-header-left`}>
            {intl.get('personal_access_token_exist')}&nbsp;{list ? list.length : 0}
          </div>
          <div className={`${prefix}-list-header-right`}>
            <Button
              type="primary"
              onClick={() => {
                this.setState({
                  isModalShow: true,
                  newToken: false,
                });
              }}
            >
              {intl.get('personal_access_token_create')}
            </Button>
          </div>
        </div>
        <div className={`${prefix}-list`}>{listJsx}</div>
      </div>
    );
  };

  render() {
    const { scopes, isModalShow, modalData, modalType } = this.state;

    return (
      <div className={prefix}>
        <div className={`${prefix}-content`}>
          {this.renderTitle()}
          <div className={`${prefix}-bottom`}>
            {!isModalShow && this.renderList()}
            {isModalShow && (
              <SelectScope
                scopes={scopes}
                vpc={this.props.vpc}
                onOk={(newToken) => {
                  this.setState({
                    newToken,
                  });
                  this.getList(1);
                }}
                data={modalData}
                type={modalType}
                onClose={() => {
                  this.setState({
                    isModalShow: false,
                    modalData: null,
                    modalType: 'new',
                  });
                }}
              />
            )}
          </div>
        </div>
      </div>
    );
  }
}
